package com.nlina.qiniu_bigwork.service;

import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.FileInfo;
import com.qiniu.storage.model.FileListing;
import com.qiniu.util.Auth;
import com.nlina.qiniu_bigwork.config.QiniuConfig;
import com.nlina.qiniu_bigwork.model.FileDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import jakarta.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;
import java.net.URLEncoder;
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.InputStream;
import java.io.ByteArrayOutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.stream.Collectors;
import java.io.FileOutputStream;
import java.io.FileInputStream;

/**
 * 七牛云存储服务类
 * 封装了对七牛云对象存储的所有操作，包括文件上传、下载、查询和删除等功能
 * 作为应用的核心服务层，为控制器提供云存储能力
 */
@Service
public class QiniuService {
    
    private static final Logger log = LoggerFactory.getLogger(QiniuService.class);
    
    /**
     * 支持直接预览的图片文件扩展名列表
     */
    private static final String[] IMAGE_EXTENSIONS = {".png", ".jpg", ".jpeg", ".gif"};

    /**
     * 七牛云配置信息，包含AK、SK、存储空间名和域名
     */
    @Autowired
    private QiniuConfig qiniuConfig;
    
    /**
     * 服务初始化方法，在Spring容器启动时自动执行
     * 验证配置参数并测试七牛云连接是否正常
     * 
     * @throws RuntimeException 如果配置无效或连接异常
     */
    @PostConstruct
    public void init() {
        log.info("七牛云服务初始化: AK={}..., Bucket={}, Domain={}", 
            qiniuConfig.getAccessKey().substring(0, 5) + "***", 
            qiniuConfig.getBucket(), 
            qiniuConfig.getDomain());
        
        // 验证配置完整性
        validateOrThrow(qiniuConfig.getAccessKey(), "AccessKey未配置");
        validateOrThrow(qiniuConfig.getSecretKey(), "SecretKey未配置");
        validateOrThrow(qiniuConfig.getBucket(), "Bucket未配置");
        validateOrThrow(qiniuConfig.getDomain(), "Domain未配置");
        
        // 测试认证
        try {
            // 尝试获取上传令牌验证认证是否正常，不需要存储返回值
            getAuth().uploadToken(qiniuConfig.getBucket());
            log.info("七牛云认证正常");
        } catch (Exception e) {
            log.error("七牛云认证失败", e);
            throw new RuntimeException("七牛云认证失败", e);
        }
    }
    
    /**
     * 验证配置值是否有效，无效则抛出异常
     * 
     * @param value 要验证的配置值
     * @param message 验证失败时的错误信息
     * @throws IllegalArgumentException 如果配置值为空
     */
    private void validateOrThrow(String value, String message) {
        if (value == null || value.isEmpty()) {
            log.error(message);
            throw new IllegalArgumentException(message);
        }
    }

    /**
     * 获取七牛云认证对象
     * 
     * @return 七牛云Auth对象
     */
    private Auth getAuth() {
        return Auth.create(qiniuConfig.getAccessKey(), qiniuConfig.getSecretKey());
    }

    /**
     * 获取七牛云存储空间管理器
     * 
     * @return 七牛云BucketManager对象
     */
    private BucketManager getBucketManager() {
        Configuration cfg = new Configuration(Region.autoRegion());
        return new BucketManager(getAuth(), cfg);
    }

    /**
     * 获取七牛云文件上传管理器
     * 
     * @return 七牛云UploadManager对象
     */
    private UploadManager getUploadManager() {
        Configuration cfg = new Configuration(Region.autoRegion());
        return new UploadManager(cfg);
    }
    
    /**
     * 格式化文件URL，确保URL格式正确并添加访问令牌
     * 
     * @param key 文件的键名
     * @return 完整的访问URL
     */
    private String formatFileUrl(String key) {
        if (key == null) {
            return qiniuConfig.getDomain();
        }
        
        String domain = qiniuConfig.getDomain();
        
        // 确保域名有协议前缀
        if (!domain.startsWith("http://") && !domain.startsWith("https://")) {
            domain = "http://" + domain;
        }
        
        // 移除域名末尾的斜杠
        if (domain.endsWith("/")) {
            domain = domain.substring(0, domain.length() - 1);
        }
        
        // 移除文件名开头的斜杠
        if (key.startsWith("/")) {
            key = key.substring(1);
        }
        
        // 生成基本URL
        String baseUrl = domain + "/" + key;
        
        // 为URL添加访问令牌（1小时有效期）
        try {
            return getAuth().privateDownloadUrl(baseUrl, 3600);
        } catch (Exception e) {
            log.error("生成带令牌的URL失败", e);
            return baseUrl;
        }
    }

    /**
     * 验证七牛云配置是否有效
     * 
     * @return true表示配置有效，false表示配置无效
     */
    public boolean validateConfig() {
        try {
            // 检查所有必需配置参数
            if (qiniuConfig.getAccessKey() == null || qiniuConfig.getAccessKey().isEmpty() ||
                qiniuConfig.getSecretKey() == null || qiniuConfig.getSecretKey().isEmpty() ||
                qiniuConfig.getBucket() == null || qiniuConfig.getBucket().isEmpty() ||
                qiniuConfig.getDomain() == null || qiniuConfig.getDomain().isEmpty()) {
                return false;
            }
            
            // 尝试获取上传凭证，验证认证是否成功
            String token = getAuth().uploadToken(qiniuConfig.getBucket());
            return token != null && !token.isEmpty();
        } catch (Exception e) {
            log.error("验证七牛云配置时发生错误", e);
            return false;
        }
    }

    /**
     * 获取七牛云上传凭证
     * 
     * @return 七牛云上传凭证字符串
     */
    public String getUploadToken() {
        return getAuth().uploadToken(qiniuConfig.getBucket());
    }

    /**
     * 上传文件到七牛云存储
     * 
     * @param file 要上传的文件对象
     * @param fileName 上传后的文件名
     * @return 上传成功后的访问URL，失败返回null
     * @throws IOException 如果上传过程出错
     */
    public String uploadFile(MultipartFile file, String fileName) throws IOException {
        try {
            // 获取上传凭证
            String upToken = getUploadToken();
            // 执行上传操作
            Response response = getUploadManager().put(file.getBytes(), fileName, upToken);
            
            // 处理上传结果
            if (response != null && response.isOK()) {
                String url = formatFileUrl(fileName);
                log.info("文件上传成功: {}", url);
                return url;
            } else {
                log.error("七牛云上传失败: {}", response != null ? response.error : "响应为null");
                return null;
            }
        } catch (QiniuException e) {
            log.error("七牛云上传异常: {}", e.getMessage(), e);
            throw new IOException("七牛云上传失败: " + e.getMessage(), e);
        }
    }

    /**
     * 获取七牛云存储空间中的文件列表
     * 
     * @param prefix 文件名前缀过滤条件（可选）
     * @param limit 最大获取数量
     * @return 文件信息列表
     * @throws QiniuException 如果查询过程出错
     */
    public List<FileDto> listFiles(String prefix, int limit) throws QiniuException {
        List<FileDto> fileList = new ArrayList<>();
        if (limit <= 0) limit = 1000;
        
        try {
            // 调用七牛API获取文件列表
            FileListing fileListing = getBucketManager().listFiles(
                    qiniuConfig.getBucket(), prefix, null, limit, null);
            
            // 检查结果是否有效
            if (fileListing == null || fileListing.items == null) {
                return fileList;
            }
            
            // 转换为应用的DTO对象
            for (FileInfo item : fileListing.items) {
                if (item == null) continue;
                
                FileDto fileDto = new FileDto();
                fileDto.setKey(item.key);
                fileDto.setMimeType(item.mimeType);
                fileDto.setSize(item.fsize);
                fileDto.setPutTime(item.putTime / 10000000); // 转换为秒
                fileDto.setUrl(formatFileUrl(item.key));
                fileDto.setEtag(item.hash);
                fileDto.setStorageType(item.type == 0 ? "标准存储" : "低频存储");
                fileList.add(fileDto);
            }
            
            return fileList;
        } catch (QiniuException qe) {
            int code = qe.code();
            
            // 特殊错误码处理
            if (code == 612 || code == 631 || code == 298) {
                log.info("七牛云特殊错误: {}", qe.getMessage());
                return fileList;
            }
            
            throw qe;
        }
    }

    /**
     * 从七牛云存储中删除文件
     * 
     * @param fileName 要删除的文件名
     * @return true表示删除成功，false表示删除失败
     */
    public boolean deleteFile(String fileName) {
        try {
            getBucketManager().delete(qiniuConfig.getBucket(), fileName);
            return true;
        } catch (QiniuException e) {
            // 612错误表示文件不存在，视为删除成功
            return e.code() == 612;
        }
    }
    
    /**
     * 获取文件的下载链接
     * 支持图片文件的直接预览和非图片文件的下载
     * 
     * @param fileName 文件名
     * @return 带有认证信息的下载链接，有效期1小时
     */
    public String getDownloadUrl(String fileName) {
        try {
            log.info("获取下载链接开始: {}", fileName);
            
            // 首先验证文件是否存在
            FileInfo fileInfo = null;
            try {
                fileInfo = getBucketManager().stat(qiniuConfig.getBucket(), fileName);
                if (fileInfo == null) {
                    throw new RuntimeException("文件不存在: " + fileName);
                }
                log.info("文件信息验证成功: key={}, size={}, mimeType={}", 
                    fileInfo.key, fileInfo.fsize, fileInfo.mimeType);
            } catch (QiniuException e) {
                if (e.code() == 612) { // 文件不存在
                    throw new RuntimeException("文件不存在: " + fileName);
                }
                throw new RuntimeException("获取文件信息失败: " + e.getMessage());
            }
            
            // 使用文件的实际key
            String key = fileInfo.key;
            if (key == null || key.isEmpty()) {
                key = fileName;
            }
            log.info("使用文件key: {}", key);
            
            // 获取基本URL
            String domain = qiniuConfig.getDomain();
            log.info("原始域名: {}", domain);
            
            // 确保域名有协议前缀
            if (!domain.startsWith("http://") && !domain.startsWith("https://")) {
                domain = "http://" + domain;
            }
            
            // 移除域名末尾的斜杠
            if (domain.endsWith("/")) {
                domain = domain.substring(0, domain.length() - 1);
            }
            log.info("处理后域名: {}", domain);
            
            // 不对key进行URL编码，让七牛云SDK处理
            String baseUrl = domain + "/" + key;
            log.info("基础URL: {}", baseUrl);
            
            // 生成私有下载链接（1小时有效期）
            String downloadUrl = getAuth().privateDownloadUrl(baseUrl, 3600);
            log.info("私有访问URL: {}", downloadUrl);
            
            return downloadUrl;
        } catch (Exception e) {
            log.error("获取下载链接失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取下载链接失败: " + e.getMessage(), e);
        }
    }
    
    /**
     * 获取文件的详细信息
     * 
     * @param fileName 文件名
     * @return 文件的详细信息，如果文件不存在则返回null
     * @throws QiniuException 如果查询过程出错
     */
    public FileDto getFileInfo(String fileName) throws QiniuException {
        try {
            // 获取文件元数据
            FileInfo fileInfo = getBucketManager().stat(qiniuConfig.getBucket(), fileName);
            
            if (fileInfo != null) {
                // 转换为应用的DTO对象
                FileDto fileDto = new FileDto();
                fileDto.setKey(fileInfo.key != null ? fileInfo.key : fileName);
                fileDto.setMimeType(fileInfo.mimeType != null ? fileInfo.mimeType : "unknown/unknown");
                fileDto.setSize(fileInfo.fsize);
                fileDto.setPutTime(fileInfo.putTime / 10000000);
                fileDto.setEtag(fileInfo.hash != null ? fileInfo.hash : "未知");
                fileDto.setStorageType(fileInfo.type == 0 ? "标准存储" : "低频存储");
                fileDto.setUrl(formatFileUrl(fileDto.getKey()));
                
                return fileDto;
            }
            return null;
        } catch (QiniuException e) {
            // 612错误表示文件不存在
            if (e.code() == 612) {
                return null;
            }
            throw e;
        }
    }

    /**
     * 重命名文件（七牛云不支持直接重命名，需要复制后删除）
     * 
     * @param oldFileName 原文件名
     * @param newFileName 新文件名
     * @return 是否重命名成功
     * @throws QiniuException 如果操作失败
     */
    public boolean renameFile(String oldFileName, String newFileName) throws QiniuException {
        if (oldFileName == null || newFileName == null || oldFileName.isEmpty() || newFileName.isEmpty()) {
            return false;
        }
        
        // 如果原文件名和新文件名相同，视为成功
        if (oldFileName.equals(newFileName)) {
            return true;
        }
        
        BucketManager bucketManager = getBucketManager();
        
        try {
            // 1. 从旧文件复制创建新文件
            bucketManager.copy(qiniuConfig.getBucket(), oldFileName, qiniuConfig.getBucket(), newFileName, true);
            log.info("文件已复制: {} -> {}", oldFileName, newFileName);
            
            // 2. 删除旧文件
            bucketManager.delete(qiniuConfig.getBucket(), oldFileName);
            log.info("原文件已删除: {}", oldFileName);
            
            return true;
        } catch (QiniuException e) {
            log.error("重命名文件失败: {} -> {}, 错误: {}", oldFileName, newFileName, e.getMessage(), e);
            throw e;
        }
    }
    
    /**
     * 生成带有有效期的共享链接
     * 
     * @param fileName 文件名
     * @param expiresInHours 有效期（小时），0表示永久有效
     * @return 共享链接
     */
    public String generateShareLink(String fileName, int expiresInHours) {
        if (fileName == null || fileName.isEmpty()) {
            return null;
        }
        
        try {
            // 基本URL
            String baseUrl = formatFileUrl(fileName);
            
            // 不设置有效期就返回公共访问链接
            if (expiresInHours <= 0) {
                return baseUrl;
            }
            
            // 设置过期时间（单位：秒）
            long expireInSeconds = expiresInHours * 3600;
            
            // 获取私有下载链接
            String privateUrl = getAuth().privateDownloadUrl(baseUrl, expireInSeconds);
            
            log.info("生成共享链接: {}, 有效期: {}小时", fileName, expiresInHours);
            return privateUrl;
        } catch (Exception e) {
            log.error("生成共享链接失败: {}, 错误: {}", fileName, e.getMessage(), e);
            return null;
        }
    }

    /**
     * 直接从七牛云下载文件
     * 
     * @param fileName 文件名
     * @return 文件字节数组
     * @throws Exception 如果下载失败
     */
    public byte[] downloadFile(String fileName) throws Exception {
        try {
            log.info("开始下载文件: {}", fileName);
            
            // 获取文件信息以验证文件存在
            FileInfo fileInfo = getBucketManager().stat(qiniuConfig.getBucket(), fileName);
            if (fileInfo == null) {
                throw new Exception("文件不存在: " + fileName);
            }
            log.info("文件信息验证成功: size={}, mimeType={}", fileInfo.fsize, fileInfo.mimeType);
            
            // 使用Java原生HTTP连接，不依赖SDK的HTTP客户端
            String domain = qiniuConfig.getDomain();
            log.info("原始域名: {}", domain);
            
            // 确保使用HTTP而非HTTPS
            if (domain.startsWith("https://")) {
                domain = "http://" + domain.substring(8);
            } else if (!domain.startsWith("http://")) {
                domain = "http://" + domain;
            }
            log.info("处理后域名: {}", domain);
            
            // 移除域名末尾的斜杠
            if (domain.endsWith("/")) {
                domain = domain.substring(0, domain.length() - 1);
            }
            
            // 构建下载URL
            String key = fileName;
            if (key.startsWith("/")) {
                key = key.substring(1);
            }
            
            // URL编码文件名
            key = URLEncoder.encode(key, "UTF-8").replace("+", "%20");
            
            String baseUrl = domain + "/" + key;
            log.info("基础URL: {}", baseUrl);
            
            String downloadUrl = getAuth().privateDownloadUrl(baseUrl, 3600);
            log.info("最终下载URL: {}", downloadUrl);
            
            // 使用Java原生HTTP连接
            URL url = new URL(downloadUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.setConnectTimeout(10000);
            connection.setReadTimeout(60000);
            
            // 检查响应码
            int responseCode = connection.getResponseCode();
            log.info("HTTP响应码: {}", responseCode);
            
            if (responseCode != HttpURLConnection.HTTP_OK) {
                // 如果失败，记录响应头信息以便调试
                connection.getHeaderFields().forEach((headerName, headerValue) -> 
                    log.info("响应头 {}: {}", headerName, headerValue));
                    
                throw new Exception("下载失败，HTTP响应码: " + responseCode);
            }
            
            // 读取文件内容
            try (InputStream in = connection.getInputStream();
                 ByteArrayOutputStream out = new ByteArrayOutputStream()) {
                byte[] buffer = new byte[8192];
                int bytesRead;
                int totalBytes = 0;
                
                while ((bytesRead = in.read(buffer)) != -1) {
                    out.write(buffer, 0, bytesRead);
                    totalBytes += bytesRead;
                    log.debug("已下载: {} bytes", totalBytes);
                }
                
                byte[] data = out.toByteArray();
                log.info("成功下载文件: {}, 大小: {} bytes", fileName, data.length);
                return data;
            }
        } catch (Exception e) {
            log.error("下载文件失败: {}, 错误: {}", fileName, e.getMessage(), e);
            throw new Exception("下载文件失败: " + e.getMessage(), e);
        }
    }

    /**
     * 获取文件输入流
     * 
     * @param fileName 文件名
     * @return 文件输入流
     * @throws Exception 如果下载失败
     */
    public InputStream getFileInputStream(String fileName) throws Exception {
        try {
            log.info("获取文件输入流开始: {}", fileName);
            
            // 创建临时文件
            java.io.File tempFile = java.io.File.createTempFile("qiniu_download_", "_temp");
            tempFile.deleteOnExit();
            log.info("创建临时文件: {}", tempFile.getAbsolutePath());

            // 构建公共URL (不使用私有访问令牌)
            String domain = qiniuConfig.getDomain();
            log.info("原始域名: {}", domain);
            
            // 确保域名格式正确
            if (!domain.startsWith("http://") && !domain.startsWith("https://")) {
                domain = "http://" + domain;
            }
            if (domain.endsWith("/")) {
                domain = domain.substring(0, domain.length() - 1);
            }
            log.info("处理后域名: {}", domain);
            
            // 对文件名进行URL编码
            String encodedFileName = URLEncoder.encode(fileName, "UTF-8").replace("+", "%20");
            log.info("编码后的文件名: {}", encodedFileName);
            
            // 构建公共URL
            String publicUrl = domain + "/" + encodedFileName;
            log.info("公共URL: {}", publicUrl);
            
            // 添加私有访问令牌
            String privateUrl = getAuth().privateDownloadUrl(publicUrl, 3600);
            log.info("私有URL: {}", privateUrl);
            
            // 使用HttpURLConnection直接下载
            URL url = new URL(privateUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.setConnectTimeout(30000);
            connection.setReadTimeout(120000);
            connection.setInstanceFollowRedirects(true);
            
            // 添加必要的请求头
            connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36");
            connection.setRequestProperty("Accept", "*/*");
            connection.setRequestProperty("Cache-Control", "no-cache");
            
            // 打印所有请求头
            Map<String, List<String>> requestHeaders = connection.getRequestProperties();
            for (Map.Entry<String, List<String>> entry : requestHeaders.entrySet()) {
                log.info("请求头 {}: {}", entry.getKey(), entry.getValue());
            }
            
            // 连接并获取响应
            connection.connect();
            int responseCode = connection.getResponseCode();
            log.info("HTTP响应码: {}", responseCode);
            
            // 打印所有响应头
            Map<String, List<String>> responseHeaders = connection.getHeaderFields();
            for (Map.Entry<String, List<String>> entry : responseHeaders.entrySet()) {
                if (entry.getKey() != null) {
                    log.info("响应头 {}: {}", entry.getKey(), entry.getValue());
                }
            }
            
            if (responseCode != HttpURLConnection.HTTP_OK) {
                // 读取错误流
                String errorContent = "";
                if (connection.getErrorStream() != null) {
                    try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getErrorStream(), "UTF-8"))) {
                        errorContent = reader.lines().collect(Collectors.joining("\n"));
                    }
                }
                log.error("下载失败，HTTP响应码: {}, 错误内容: {}", responseCode, errorContent);
                throw new Exception("下载失败，HTTP响应码: " + responseCode);
            }
            
            // 获取内容类型和长度
            String contentType = connection.getContentType();
            int contentLength = connection.getContentLength();
            log.info("内容类型: {}, 内容长度: {} 字节", contentType, contentLength);
            
            // 读取文件内容到临时文件
            try (InputStream in = connection.getInputStream();
                 FileOutputStream out = new FileOutputStream(tempFile)) {
                byte[] buffer = new byte[8192];
                int bytesRead;
                long totalBytes = 0;
                while ((bytesRead = in.read(buffer)) != -1) {
                    out.write(buffer, 0, bytesRead);
                    totalBytes += bytesRead;
                    if (totalBytes % (1024 * 1024) == 0) {
                        log.debug("已下载: {} MB", totalBytes / (1024 * 1024));
                    }
                }
                log.info("文件已下载到临时文件: {}, 大小: {} 字节", tempFile.getAbsolutePath(), totalBytes);
            }
            
            // 返回文件输入流
            return new FileInputStream(tempFile);
        } catch (Exception e) {
            log.error("获取文件输入流失败: {}", e.getMessage(), e);
            throw new Exception("获取文件输入流失败: " + e.getMessage(), e);
        }
    }

    /**
     * 直接获取文件的字节数组，不使用URL下载
     * 
     * @param fileName 文件名
     * @return 文件的字节数组
     * @throws Exception 如果下载失败
     */
    public byte[] getFileBytes(String fileName) throws Exception {
        log.info("开始获取文件字节数组: {}", fileName);
        
        try {
            // 验证文件存在
            FileInfo fileInfo = null;
            try {
                fileInfo = getBucketManager().stat(qiniuConfig.getBucket(), fileName);
                if (fileInfo == null) {
                    throw new Exception("文件不存在: " + fileName);
                }
                log.info("文件信息验证成功: key={}, size={}, mimeType={}", 
                    fileInfo.key, fileInfo.fsize, fileInfo.mimeType);
            } catch (QiniuException e) {
                if (e.code() == 612) { // 文件不存在
                    throw new Exception("文件不存在: " + fileName);
                }
                throw new Exception("获取文件信息失败: " + e.getMessage());
            }
            
            // 使用文件的实际key
            String key = fileInfo.key;
            if (key == null || key.isEmpty()) {
                key = fileName;
            }
            log.info("使用文件key: {}", key);
            
            // 创建临时文件
            java.io.File tempFile = java.io.File.createTempFile("qiniu_download_", "_temp");
            tempFile.deleteOnExit();
            log.info("创建临时文件: {}", tempFile.getAbsolutePath());
            
            // 获取下载链接
            String domain = qiniuConfig.getDomain();
            if (!domain.startsWith("http://") && !domain.startsWith("https://")) {
                domain = "http://" + domain;
            }
            if (domain.endsWith("/")) {
                domain = domain.substring(0, domain.length() - 1);
            }
            
            // 使用privateUrl方法获取私有空间文件
            String baseUrl = String.format("%s/%s", domain, key);
            String privateUrl = getAuth().privateDownloadUrl(baseUrl, 3600);
            log.info("私有访问URL: {}", privateUrl);
            
            // 使用Java HTTP客户端下载
            URL url = new URL(privateUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(30000);
            conn.setReadTimeout(60000);
            conn.setRequestProperty("User-Agent", "Mozilla/5.0");
            conn.setRequestProperty("Accept", "*/*");
            
            // 连接并检查响应
            conn.connect();
            int responseCode = conn.getResponseCode();
            log.info("HTTP响应码: {}", responseCode);
            
            if (responseCode != HttpURLConnection.HTTP_OK) {
                String errorMsg = "下载失败，HTTP响应码: " + responseCode;
                throw new Exception(errorMsg);
            }
            
            // 读取响应内容到字节数组
            try (InputStream in = conn.getInputStream();
                 ByteArrayOutputStream out = new ByteArrayOutputStream()) {
                byte[] buffer = new byte[8192];
                int bytesRead;
                while ((bytesRead = in.read(buffer)) != -1) {
                    out.write(buffer, 0, bytesRead);
                }
                byte[] data = out.toByteArray();
                log.info("成功下载文件: {}, 大小: {} bytes", fileName, data.length);
                return data;
            }
        } catch (Exception e) {
            log.error("获取文件字节数组失败: {}", e.getMessage(), e);
            throw new Exception("获取文件字节数组失败: " + e.getMessage(), e);
        }
    }
} 